package cn.skylark.wcm.service.impl;

import cn.skylark.wcm.dao.FileTableDao;
import cn.skylark.wcm.entity.Filetable;
import cn.skylark.wcm.service.FileManagerService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;
import tk.mybatis.mapper.entity.Example;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

@Service
public class FileManagerServiceImpl implements FileManagerService {
    Logger logger = LoggerFactory.getLogger(FileManagerServiceImpl.class);
    @Autowired
    public FileTableDao fileTableDao;

    /**
     * 逻辑删除表格中的数据
     *
     * @param id 文件id
     */
    @Override
    public void delete(Integer id, Integer type) {
        logger.info("逻辑删除文件开始==" + "id=" + id + "type=" + type);
        //根据id判断是否为文件夹，如果不是文件夹的话直接进行逻辑删除
        Filetable filetable = new Filetable();
        filetable.setId(id);
        filetable.setDelflg(0);
        filetable.setType(type);
        filetable = fileTableDao.selectOne(filetable);

        //判断suffix是否为空
        if (filetable.getSuffix() != null && !"".equals( filetable.getSuffix() )) {
            //文件的情况
            Filetable deleteFiletable = new Filetable();
            deleteFiletable.setLocalpath( filetable.getLocalpath() );
            deleteFiletable.setFilename( filetable.getFilename() );
            List<Filetable> filetableList = fileTableDao.select( deleteFiletable );
            Date date = new Date();
            for (Filetable file : filetableList) {
                file.setDelflg( 1 );
                file.setUpdatetime( date );
                file.setRecycleflg( id );
                fileTableDao.updateById( file );
            }
        } else {
            //为文件夹的情况，先模糊查询他下面的所有，然后进行伦理删除
            String localpath = filetable.getLocalpath();
            String filename = filetable.getFilename();
            localpath = localpath + filename;
            Example example = new Example( Filetable.class );
            Example.Criteria criteria = example.createCriteria();
            criteria.andLike( "localpath", localpath + "%" );
            criteria.andEqualTo( "recycleflg", null );
            if (filetable.getType()==0){
                criteria.andEqualTo("type",filetable.getType());
            }else {
                criteria.andBetween( "type", filetable.getType(), 3 );
            }
            criteria.andEqualTo( "delflg", 0 );
            criteria.andEqualTo( "userid", filetable.getUserid() );
            List<Filetable> fileList = fileTableDao.selectByExample( example );
            for (int i = 0; i < fileList.size(); i++) {
                //删除它下面的所有文件和文件夹
                Date date = new Date();
                Filetable filetable1 = fileList.get( i );
                filetable1.setId( filetable1.getId() );
                filetable1.setDelflg( 1 );
                filetable1.setUpdatetime( date );
                filetable1.setRecycleflg( filetable.getId() );
                fileTableDao.updateById( filetable1 );
            }
            //删除其本身
            filetable.setDelflg( 1 );
            filetable.setRecycleflg( filetable.getId() );
            Date date = new Date();
            filetable.setUpdatetime( date );
            fileTableDao.updateById( filetable );
        }
        logger.info("逻辑删除文件结束==");
    }

    /**
     * 批量删除文件
     *
     * @param ids 数组
     */
    @Override
    public void batchDelete(String[] ids) {
        logger.info("批量逻辑删除文件开始==" + "ids=" + ids);
        //对所传的数组进行循环依次删除
        for (int i = 0; i < ids.length; i++) {
            int id = Integer.valueOf(ids[i]);
            Filetable filetable = selectById(Integer.valueOf(ids[i]));
            //调用单个删除的方法
            this.delete(id, filetable.getType());
        }
        logger.info("批量逻辑删除文件结束==");

    }

    /**
     * 新建文件夹
     *
     * @param filetable 文件的实体类
     */
    @Override
    public void saveFolder(Filetable filetable) {
        Integer type = 0;
        if (filetable.getType() != null || !"".equals(filetable.getType())) {
            type = filetable.getType();
        }
        filetable.setDelflg(0);
        filetable.setType(type);
        filetable.setLocalpath(filetable.getLocalpath());
        filetable.setSuffix("");
        filetable.setSize("");
        fileTableDao.insert(filetable);
    }

    /**
     * 根据条件进行查询该文件夹是否存在
     *
     * @param filetable 文件实体类
     * @return
     */
    @Override
    public Filetable selectByParameter(Filetable filetable) {
        logger.info("查询文件夹是否存在开始" + "filetable:" + filetable);
        Example example = new Example(Filetable.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userid", filetable.getUserid());
        criteria.andEqualTo("tenanid", filetable.getTenanid());
        criteria.andCondition("(suffix=''or suffix is Null)");
        criteria.andEqualTo("localpath", filetable.getLocalpath());
        criteria.andEqualTo("filename", filetable.getFilename());
        criteria.andEqualTo("type", filetable.getType());
        criteria.andEqualTo("delflg",0);
        List<Filetable> filetables = fileTableDao.selectByExample(example);
        if (filetables.size() > 0) {
            return filetables.get(0);
        }
        logger.info("查询文件夹是否存在结束");
        return null;
    }

    /**
     * 查询视频的分页列表
     *
     * @param filetable 文件的实体类
     * @param start     开始是第几条
     * @param length    每页多少数据
     * @return
     */
    @Override
    public PageInfo<Filetable> selectVideoListByParameter(Filetable filetable, String flag, int start, int length, String filename) {
        logger.info("分页获取文件夹内信息开始--Filetable" + filetable + "start" + start + "length" + length);
        int page = start / length + 1;
        Example example = new Example(Filetable.class);
        Example.Criteria criteria = example.createCriteria();
        if ("0".equals(flag)) {
            if (filetable.getLocalpath() == null) {
                filetable.setLocalpath("");
            }
            criteria.andEqualTo("userid", filetable.getUserid());
            criteria.andEqualTo("tenanid", filetable.getTenanid());
            criteria.andEqualTo("delflg", 0);
            criteria.andEqualTo("type", filetable.getType());
            if (filename == null || "".equals(filename)) {
                filename = "";
            }
            criteria.andLike("filename", "%" + filename + "%");
            StringBuffer sb = new StringBuffer();
            sb.append("('avi','mp4','rmvb','wmv')");
            criteria.andCondition("suffix in" + sb.toString());
        } else if ("1".equals(flag)) {
            if (filetable.getLocalpath() == null) {
                filetable.setLocalpath("");
            }
            criteria.andEqualTo("delflg", 0);
            criteria.andEqualTo("type", filetable.getType());
            if (filename == null || "".equals(filename)) {
                filename = "";
            }
            criteria.andLike("filename", "%" + filename + "%");
            StringBuffer sb = new StringBuffer();
            sb.append("('avi','mp4','rmvb','wmv')");
            criteria.andCondition("suffix in" + sb.toString());
        }
        // 分页查询
        PageHelper.startPage(page, length);
        List<Filetable> filetableList = fileTableDao.selectByExample(example);
        logger.info("分页获取文件夹内信息开始");
        return new PageInfo<>(filetableList);
    }

    /**
     * 查询该id下的实体类
     *
     * @param id 文件id
     * @return
     */
    @Override
    public Filetable selectById(Integer id) {
        Filetable filetable = new Filetable();
        filetable.setId(id);
        return fileTableDao.selectOne(filetable);
    }

    /**
     * 获取该租户下的已经用掉的储存空间
     *
     * @param tenanid 租户id
     * @return
     */
    @Override
    public String getTotalSize(Integer tenanid) {
        return fileTableDao.getTotalSize(tenanid);
    }

    /**
     * 通过条件获得实体类的通用方法
     *
     * @param filetable 文件的实体类
     */
    @Override
    public Filetable selectOne(Filetable filetable) {
        return fileTableDao.selectOne(filetable);
    }

    /**
     * 把图片进行base64转码
     * 1.
     *
     * @param imgPath 图片路径
     * @return
     */
    @Override
    public String base64Convert(String imgPath) {
        logger.info("通过图片路径进行base64的转码开始======" + imgPath);
        InputStream in = null;
        byte[] data = null;
        //  读取图片字节数组
        try {
            in = new FileInputStream(imgPath);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //  对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        //  返回Base64编码过的字节数组字符串
        String picStr = encoder.encode(data);
        logger.info("通过图片路径进行base64的转码结束======");
        return picStr;
    }

    /**
     * 分页查询获取所有文件信息列表
     * 1.查询条件是userid和tenanid 获取初始化列表
     * 2.根据传过来的查询条件，获取到相应的列表
     *
     * @param filetable
     * @param start     从第几页开始
     * @param length    每页多少个
     * @return
     */
    @Override
    public PageInfo<Filetable> selectInitFileListByParameter(Filetable filetable, String flag, int start, int length, String filename) {
        logger.info("分页获取文件信息--Filetable" + filetable + "start" + start + "length" + length);
        int page = start / length + 1;
        Example example = new Example(Filetable.class);
        Example.Criteria criteria = example.createCriteria();
        //判断传过来的flag的情况
        if ("0".equals(flag)) {
            criteria.andEqualTo("localpath", "");
            criteria.andEqualTo("userid", filetable.getUserid());
            criteria.andEqualTo("tenanid", filetable.getTenanid());
            criteria.andEqualTo("delflg", 0);
            criteria.andEqualTo("type", 0);
            criteria.andCondition("suffix not in('mp4','avi','rmvb','html','htm')");
            if (null == filename || "".equals(filename)) {
                filename = "";
            }
            criteria.andLike("filename", "%" + filename + "%");
            example.setOrderByClause("updatetime desc");
        } else if ("1".equals(flag)) {
            criteria.andEqualTo("localpath", "");
            criteria.andEqualTo("delflg", 0);
            criteria.andEqualTo("type", 0);
            if (null == filename || "".equals(filename)) {
                filename = "";
            }
            criteria.andLike("filename", "%" + filename + "%");
            example.setOrderByClause("updatetime desc");
        }

        // 分页查询
        PageHelper.startPage(page, length);
        List<Filetable> filetableList = fileTableDao.selectByExample(example);
        logger.info("分页获取用户信息结束");
        return new PageInfo<>(filetableList);
    }

    /**
     * 分页查询获取所有的文件夹内信息
     * 1.查询条件是userid和tenanid filename和localpath进行查询
     * 2.查询到所有文件夹下面的文件。
     *
     * @param filetable 文件的实体类
     * @param start     开始为第几条
     * @param length    每页多少个
     * @param flag      标志位
     * @param filename  查询条件
     * @return
     */
    @Override
    public PageInfo<Filetable> selectByPageFolder(Filetable filetable, String flag,  int start, int length,String filename) {
        logger.info("分页获取文件夹内信息开始--Filetable" + filetable + "start" + start + "length" + length);
        int page = start / length + 1;
        Example example = new Example(Filetable.class);
        Example.Criteria criteria = example.createCriteria();
        if (filetable.getLocalpath() == null) {
            filetable.setLocalpath("");
        }
        criteria.andEqualTo("localpath", filetable.getLocalpath() + filetable.getFilename() + "/");
        criteria.andEqualTo("userid", filetable.getUserid());
        criteria.andEqualTo("tenanid", filetable.getTenanid());
        criteria.andEqualTo("type", 0);
        criteria.andEqualTo("delflg", 0);
        criteria.andLike("filename", "%" + filename + "%");
        example.setOrderByClause("updatetime desc");
        // 分页查询
        PageHelper.startPage(page, length);
        List<Filetable> filetableList = fileTableDao.selectByExample(example);
        logger.info("分页获取文件夹内信息开始");
        return new PageInfo<>(filetableList);
    }

    /**
     *  删除已经上传的文件
     *  业务：1.根据租户id和用户id，文件名查找到这个文件
     *        2.然后把这个文件进行物理删除。
     * @param tenanid 租户id
     * @param userid 用户id
     * @param filename 文件名
     */
    @Override
    public void deleteFileByName(String fatherid,Integer tenanid, Integer userid, String filename,Integer type) {
        logger.info("进入删除已经上传的文件开始==fatherid=="+fatherid+"==tenanid=="+tenanid+"==userid=="+userid+"==filename=="+filename);
        //然后根据fatherid是否为空判断
        String newfilename =filename.substring(0,filename.lastIndexOf("."));
        String newsuffix = filename.substring(filename.lastIndexOf(".")+1);
        if (fatherid==null||"".equals(fatherid)){
            //如果fatherid为空的话。
            Filetable f = new Filetable();
            f.setLocalpath("");
            f.setDelflg(0);
            f.setType(type);
            f.setUserid(userid);
            f.setTenanid(tenanid);
            f.setFilename(newfilename);
            f.setSuffix(newsuffix);
            fileTableDao.delete(f);
        }else{
            //有文件目录的情况,进行找到此时的租户id和用户id
            Filetable filetable = new Filetable();
            filetable.setId(Integer.valueOf(fatherid));
            Filetable newfiletable = fileTableDao.selectOne(filetable);
            String newlocalpath = newfiletable.getLocalpath();
            String fileName = newfiletable.getFilename();
            Integer newTenanid = newfiletable.getTenanid();
            Integer newuserid= newfiletable.getUserid();
            Filetable f = new Filetable();
            f.setSuffix(newsuffix);
            f.setFilename(newfilename);
            f.setTenanid(newTenanid);
            f.setUserid(newuserid);
            f.setType(type);
            f.setDelflg(0);
            f.setLocalpath(newlocalpath+fileName);
            fileTableDao.delete(f);
        }
        logger.info("进入删除已经上传的文件结束==fatherid=="+fatherid+"==tenanid=="+tenanid+"==userid=="+userid+"==filename=="+filename);
    }

}
